/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "queue.h"
#include "semphr.h"
#include "stm32f1xx_hal_flash.h"
#include "modbus_rtu.h"
#include "ina226.h"
#include "hlw8012.h"
#include "usart.h"

//#define GpuSend(...) printf(__VA_ARGS__)  
#define GpuSend(...) SOFTUART_Printf(__VA_ARGS__) 
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
// External variable declarations
extern uint16_t aADCxConvertedData[7];
extern uint8_t aa;
extern xQueueHandle xQueueRx_pc_uart1;
extern xQueueHandle xQueueRx_bms_uart2;
extern xQueueHandle xQueueRx_ac_uart3;
extern uint8_t adc_cont;

// Global variable definitions
uint8_t Status_BUS;
uint8_t BAT_EN = 1;
uint16_t temp_v;
uint16_t temp_i;
uint16_t temp_ii;
uint16_t battery_cyc = 0;
uint8_t IB1_STATE;
uint8_t IB2_STATE;
uint8_t POWER_STATE = 0;
uint8_t bms_state = 0;
uint8_t ch_stade = 1;
uint8_t ch_stade1 = 1;
uint8_t bat_stade1 = 1;
uint8_t rx_usart1_cnt;
uint8_t ModebusTxBuff[200];
uint8_t ModebusRxBuff[128];
uint16_t rtu_buff[1090] = {0};
uint8_t rx_usart3_cnt;
uint8_t ModebusTxBuff_M[128];
uint8_t ModebusRxBuff_M[128];
uint8_t bat_charge_indicator = 0;
uint8_t bat_discharge_indication = 0;
uint8_t proto = 0;
uint8_t rtu = 0;
MODEBUS_HANDLE ModebusHandle1;
MRTU_SLAVE_INFO FrameInfo1;
MODEBUS_HANDLE ModebusHandle2;
MRTU_SLAVE_INFO FrameInfo2;
uint16_t modbue_SlaveAddr = 1;
uint16_t udp_status = 0;
float SOC = 0.0f;
uint16_t SOH = 100;
float battery_capacity_rate = 20000.0f;
float battery_capacity_full = 20000.0f;
xSemaphoreHandle xSemaphoreRecf_pc_uart1;
xSemaphoreHandle xSemaphoreRecf_bms_uart2;
xSemaphoreHandle xSemaphoreRecf_ac_uart3;
uint16_t ac_v = 0;
int16_t tem;
uint16_t out = 2;
float ac_v_f = 0.0f;
float battery_v = 0.0f;
float battery_i = 0.0f;
float battery_i1 = 0.0f;
float battery_i2 = 0.0f;
float battery_i3 = 0.0f;
float battery_c = 3000.0f;
int battery_capacity = 50;
float device_tem = 37.8f;
uint8_t bat_state = 0;
uint8_t ctrl_1 = 0;
uint8_t tick_tock = 0;
uint8_t BAT_STATE1 = 1;
uint8_t out_lcd = 1;
uint16_t udp_rtu_con = 0;
uint16_t modbue_Baud = 1152;
uint16_t bat_under_charge = 80;
uint16_t OUT1_266 = 0;
uint16_t OUT2_266 = 0;
uint16_t BAT_266 = 1;
uint16_t out_sum = 3;
uint16_t pcb_sum = 1;
uint16_t ctrl_2 = 0xFFFF;
uint16_t ctrl_3 = 0xFFFF;
uint16_t ctrl_4 = 0xFFFF;
uint16_t ctrl_5 = 0xFFFF;
uint8_t add = 1;
uint8_t m_s = 1;
uint8_t out_sum_temp = 0;
float tempre = 0.0f;
float dc_v[13] = {0.0f};
float dc_i[13] = {0.0f};
uint8_t calibration_i;
uint8_t bms_add;
float v_k[13] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
float i_k[13] = {2.5f, 2.5f, 1.22f, 1.25f, 1.25f, 1.25f, 2.5f, 2.5f, 1.22f, 1.25f, 1.25f, 1.25f, 1.25f};
float i_k_a[13] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};

// BMS改进参数（NiMH充电终止与温升判据）
float delta_v_threshold_per_cell = 0.007f;   // Delta V阈值(V/节)
float charge_cutoff_current = 0.10f;         // 充电截止电流(A)
float temp_rate_threshold = 1.0f;            // 温升阈值(摄氏度/分钟)
float peak_cell_voltage = 0.0f;              // 充电过程电芯电压峰值
float last_device_tem_bms = 0.0f;            // 上一次温度采样(摄氏度)
int temp_rate_sample_count = 0;              // 温升采样计数(秒)
float temp_rate_accum = 0.0f;                // 累计温度变化(摄氏度)

// SOC积分效率参数
float charge_efficiency = 0.90f;             // 充电效率系数
float discharge_efficiency = 1.00f;          // 放电效率系数

// 待机补电与复电强充参数
float i_idle_threshold = 0.02f;              // 待机判定电流阈值(A)
int idle_debounce_seconds = 300;             // 待机去抖时长(秒)
float standby_safe_soc_threshold = 90.0f;    // 待机安全SOC阈值(%)
float standby_safe_cell_v_threshold = 1.25f; // 待机安全电芯电压阈值(V/节)
// 充电开关防抖与滞回参数
int charge_reopen_block_seconds = 120;       // 关闭充电后禁止再次打开时长(秒)
float soc_hysteresis_margin_percent = 2.0f;  // SOC滞回幅度(%)
float standby_self_discharge_rate_percent_per_day = 0.75f; // 待机自放电速率(%/天)
// SOH健康度管理参数
#define SOH_CYCLE_DEGRADATION_PER_CYCLE 0.01f  // 每循环健康度下降百分比
#define SOH_TEMPERATURE_DEGRADATION_PER_DEGREE 0.05f  // 每摄氏度健康度下降百分比
#define SOH_DEEP_DISCHARGE_DEGRADATION 0.1f     // 深度放电健康度下降百分比
#define SOH_UPDATE_INTERVAL_SECONDS 3600       // SOH更新间隔(秒)

// 电池循环计数参数
#define CYCLE_COUNT_SOC_THRESHOLD_HIGH 80.0f   // 循环计数高SOC阈值(%)
#define CYCLE_COUNT_SOC_THRESHOLD_LOW 20.0f    // 循环计数低SOC阈值(%)
#define CYCLE_COUNT_DEBOUNCE_SECONDS 300       // 循环计数防抖时长(秒)

// 温度ADC查找表（对应-40℃ ~ 125℃）
uint16_t t_adc[341] = {
    123,131,139,148,157,167,178,189,200,212,225,239,253,268,284,300,
    316,334,352,371,391,411,432,455,478,501,526,551,577,604,632,661,
    691,722,754,786,820,855,890,926,964,1000,1038,1077,1116,1156,1197,
    1238,1281,1323,1367,1410,1455,1499,1544,1590,1635,1681,1727,1773,
    1819,1865,1911,1957,2003,2048,2093,2138,2183,2227,2271,2314,2357,
    2399,2441,2482,2523,2562,2602,2640,2678,2716,2752,2788,2823,2857,
    2891,2924,2956,2988,3019,3049,3078,3106,3134,3161,3188,3214,3239,
    3263,3287,3310,3333,3355,3376,3397,3417,3437,3456,3474,3492,3510,
    3527,3543,3559,3575,3590,3604,3619,3632,3646,3659,3671,3684,3696,
    3707,3718,3729,3740,3750,3760,3770,3779,3788,3797,3806,3814,3822,
    3830,3837,3844,3851,3858,3865,3871,3877,3883,3889,3894,3900,3905,
    3910,3915,3920,3925,3929,3934,3938,3942,3946,3950,3954,3957,3961,
    3964,3968,3971,3974,3978,3981,3984,3987,3990,3993,3995,3998,4001,
    4003,4005,4008,4010,4012,4014,4016,4018,4020,4022,4024,4026,4027,
    4029,4031,4032,4034,4035,4036,4038,4039,4040,4042,4043,4044,4045,
    4046,4047,4048,4050,4051,4052,4052,4053,4054,4055,4056,4057,4058,
    4059,4059,4060,4061,4062,4063,4063,4064,4065,4065,4066,4067,4067,
    4068,4068,4069,4070,4070,4071,4071,4072,4072,4073,4073,4074,4074,
    4074,4075,4075,4076,4076,4076,4077,4077,4077,4078,4078,4078,4079,
    4079,4079,4080,4080,4080,4080,4081,4081,4081,4081,4082,4082,4082,
    4082,4083,4083,4083,4083,4084,4084,4084,4084,4085,4085,4085,4085,
    4085,4086,4086,4086,4086,4086,4086,4087,4087,4087,4087,4087,4087,
    4087,4088,4088,4088,4088,4088,4088,4088,4089,4089,4089,4089,4089,
    4089,4089,4089,4089,4089,4090,4090,4090,4090,4090,4090,4090,4090,
    4090,4090,4090,4091,4091,4091,4091,4091,4091,4091,4091,4091,4091,
    4091,4091,4092,4092,4092,4092,4092
};

int num_pic_battery = 5;    // 电池SOC显示标志(5=低电量, 1=满电量)
int num_pic_bat_status = 2; // 电池充放电状态标志
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
// Flash存储地址(STM32F103C8T6, 0x08010000为用户Flash区域)
#define FLASH_STORAGE_ADDR 0x08010000

// INA226设备配置(分流电阻:0.01Ω, 最大电流:3.2768A)
INA226_Dev dev1 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,
    .max_current = 3.2768f,
    .addr = 0x40
};

INA226_Dev dev2 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,
    .max_current = 3.2768f,
    .addr = 0x41
};

INA226_Dev dev3 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,
    .max_current = 3.2768f,
    .addr = 0x42
};

INA226_Dev dev4 = {
    .scl_port = I2C_SCL_GPIO_Port,
    .scl_pin = I2C_SCL_Pin,
    .sda_port = I2C_SDA_GPIO_Port,
    .sda_pin = I2C_SDA_Pin,
    .shunt_r = 0.01f,
    .max_current = 3.2768f,
    .addr = 0x44
};

/**
 * @brief 将校准参数和配置写入Flash
 * @param 无
 * @retval 无
 */
void writeFlashTest(void)
{
    uint8_t i;
    FLASH_EraseInitTypeDef flash_erase_init;
    uint32_t page_error = 0;

    // 解锁Flash
    HAL_FLASH_Unlock();

    // 配置Flash页擦除
    flash_erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
    flash_erase_init.PageAddress = FLASH_STORAGE_ADDR;
    flash_erase_init.NbPages = 1;
    HAL_FLASHEx_Erase(&flash_erase_init, &page_error);

    // 写入电压校准系数(13个值,每个4字节)
    for (i = 0; i <= 12; i++)
    {
        HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 4 * i, (uint32_t)(v_k[i] * 100));
    }

    // 写入电流校准系数(13个值,每个4字节)
    for (i = 0; i <= 12; i++)
    {
        HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 4 * (i + 13), (uint32_t)(i_k[i] * 100));
    }

    // 写入Modbus从机地址和UDP状态
    HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 26 * 4, (uint32_t)modbue_SlaveAddr);
    HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 27 * 4, (uint32_t)udp_status);

    // 写入电流校准系数A(13个值,每个4字节)
    for (i = 0; i <= 12; i++)
    {
        HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 4 * (i + 28), (uint32_t)(i_k_a[i] * 100));
    }

    // 写入Modbus波特率、SOH、电池循环次数、SOC
    HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 41 * 4, (uint32_t)modbue_Baud);
    HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 42 * 4, (uint32_t)SOH);
    HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 43 * 4, (uint32_t)battery_cyc);
    HAL_FLASH_Program(0x02U, FLASH_STORAGE_ADDR + 44 * 4, (uint32_t)SOC);

    // 锁定Flash
    HAL_FLASH_Lock();

    // 更新RTU缓冲区为最新配置
    rtu_buff[6] = modbue_SlaveAddr;
    rtu_buff[154] = udp_status;
    rtu_buff[4] = modbue_Baud;
    rtu_buff[5] = SOH;
    rtu_buff[7] = battery_cyc;
    rtu_buff[8] = SOC;
}

/**
 * @brief 从Flash读取校准参数和配置
 * @param 无
 * @retval 无
 */
void printFlashTest(void)
{
    uint8_t i;
    uint16_t flash_init_val = 0;

    // 读取初始Flash值(0xFFFF表示未初始化)
    flash_init_val = (uint16_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR));
    if (flash_init_val >= 0xFFFF)
    {
        writeFlashTest();  // 未初始化则写入默认值
        return;
    }

    // 读取电压校准系数
    for (i = 0; i <= 12; i++)
    {
        v_k[i] = ((float)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 4 * i))) / 100.00f;
    }

    // 读取电流校准系数
    for (i = 0; i <= 12; i++)
    {
        i_k[i] = ((float)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 4 * (i + 13)))) / 100.00f;
    }

    // 读取Modbus从机地址和UDP状态
    modbue_SlaveAddr = (uint8_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 26 * 4));
    udp_status = (uint16_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 27 * 4));

    // 读取电流校准系数A
    for (i = 0; i <= 12; i++)
    {
        i_k_a[i] = ((float)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 4 * (i + 28)))) / 100.00f;
    }

    // 读取Modbus波特率、SOH、电池循环次数、SOC
    modbue_Baud = (uint16_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 41 * 4));
    SOH = (uint16_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 42 * 4));
    battery_cyc = (uint16_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 43 * 4));
    SOC = (uint16_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR + 44 * 4));

    // 更新RTU缓冲区为读取的值
    rtu_buff[6] = modbue_SlaveAddr;
    rtu_buff[154] = udp_status;
    rtu_buff[4] = modbue_Baud;
    rtu_buff[5] = SOH;
    rtu_buff[7] = battery_cyc;
    rtu_buff[8] = SOC;
}
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
// 任务句柄和属性定义
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
    .name = "defaultTask",
    .stack_size = 128 * 4,
    .priority = (osPriority_t)osPriorityNormal,
};

osThreadId_t myLCD_TaskHandle;
const osThreadAttr_t myLCD_Task_attributes = {
    .name = "myLCD_Task",
    .stack_size = 128 * 4,
    .priority = (osPriority_t)osPriorityLow7,
};

osThreadId_t modbus_rtuHandle;
const osThreadAttr_t modbus_rtu_attributes = {
    .name = "modbus_rtu",
    .stack_size = 128 * 4,
    .priority = (osPriority_t)osPriorityLow,
};

osThreadId_t myled_TaskHandle;
const osThreadAttr_t myled_Task_attributes = {
    .name = "myled_Task",
    .stack_size = 128 * 4,
    .priority = (osPriority_t)osPriorityLow,
};

osThreadId_t mybms_taskHandle;
const osThreadAttr_t mybms_task_attributes = {
    .name = "mybms_task",
    .stack_size = 128 * 4,
    .priority = (osPriority_t)osPriorityLow,
};

osThreadId_t TC_TaskHandle;
const osThreadAttr_t TC_Task_attributes = {
    .name = "TC_Task",
    .priority = (osPriority_t)osPriorityHigh,
    .stack_size = 128 * 4
};

osThreadId_t cmd_TaskHandle;
const osThreadAttr_t cmd_Task_attributes = {
    .name = "cmd_Task",
    .priority = (osPriority_t)osPriorityNormal,
    .stack_size = 128 * 4
};

osThreadId_t hlw8012TaskHandle;
const osThreadAttr_t hlw8012Task_attributes = {
    .name = "hlw8012Task",
    .priority = (osPriority_t)osPriorityNormal,
    .stack_size = 128 * 4
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void Start_TC_Task(void *argument);
void Start_cmd_Task(void *argument);
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);
void StartLCD_Task(void *argument);
void Startmodbus_rtu(void *argument);
void Startled_Task(void *argument);
void Startbms_Task(void *argument);

/**
 * @brief  FreeRTOS初始化函数
 * @param  无
 * @retval 无
 */
void MX_FREERTOS_Init(void)
{
    /* USER CODE BEGIN Init */
    /* USER CODE END Init */

    /* USER CODE BEGIN RTOS_MUTEX */
    /* USER CODE END RTOS_MUTEX */

    /* USER CODE BEGIN RTOS_SEMAPHORES */
    /* USER CODE END RTOS_SEMAPHORES */

    /* USER CODE BEGIN RTOS_TIMERS */
    /* USER CODE END RTOS_TIMERS */

    /* USER CODE BEGIN RTOS_QUEUES */
    /* USER CODE END RTOS_QUEUES */

    // 创建默认任务
    defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

    // 创建LCD任务
    myLCD_TaskHandle = osThreadNew(StartLCD_Task, NULL, &myLCD_Task_attributes);

    // 创建Modbus RTU任务
    modbus_rtuHandle = osThreadNew(Startmodbus_rtu, NULL, &modbus_rtu_attributes);

    // 创建LED任务
    myled_TaskHandle = osThreadNew(Startled_Task, NULL, &myled_Task_attributes);

    // 创建BMS任务
    mybms_taskHandle = osThreadNew(Startbms_Task, NULL, &mybms_task_attributes);

    /* USER CODE BEGIN RTOS_THREADS */
    // 创建ADC采样任务
    TC_TaskHandle = osThreadNew(Start_TC_Task, NULL, &TC_Task_attributes);

    // 创建PC命令处理任务
    cmd_TaskHandle = osThreadNew(Start_cmd_Task, NULL, &cmd_Task_attributes);

    // 创建HLW8012测量任务
    hlw8012TaskHandle = osThreadNew(HLW8012_MeasurementTask, NULL, &hlw8012Task_attributes);
    /* USER CODE END RTOS_THREADS */

    /* USER CODE BEGIN RTOS_EVENTS */
    /* USER CODE END RTOS_EVENTS */
}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  实现defaultTask线程的函数
  * @param  argument: 未使用
  * @retval 无
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
    uint8_t temp;

    // 初始化Modbus从机(UART1, 从机地址1, 波特率: modbue_Baud*100)
    MODEBUS_slave_Init(&ModebusHandle1,
                       01,
                       modbue_Baud * 100,
                       ModebusRxBuff,
                       ModebusTxBuff,
                       128 - 1,
                       200);

    // 初始化定时器(清除更新标志, 使能更新中断, 启动计数器)
    LL_TIM_ClearFlag_UPDATE(TIM1);
    LL_TIM_EnableIT_UPDATE(TIM1);
    LL_TIM_EnableCounter(TIM3);

    // 配置ADC DMA(通道1, 数据长度1)
    LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 1);
    LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_1, LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA));
    LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)aADCxConvertedData);
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);

    // 初始化ADC(使能, 开始校准, 等待校准完成)
    LL_ADC_Enable(ADC1);
    LL_ADC_StartCalibration(ADC1);
    while (LL_ADC_IsCalibrationOnGoing(ADC1));
    LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_UNLIMITED);

    // 初始化Flash(读取或写入默认值)
    temp = (uint8_t)(*(__IO uint32_t *)(FLASH_STORAGE_ADDR));
    if (temp == 0xFF)
    {
        writeFlashTest();
    }
    else
    {
        printFlashTest();
    }

    // 系统延迟2000ms
    osDelay(2000);

    // 主循环(LED每500ms翻转一次)
    for (;;)
    {
        LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_13);
        osDelay(500);
        LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_13);
        osDelay(500);
    }
}

/* USER CODE BEGIN Header_StartLCD_Task */
/**
  * @brief  实现myLCD_Task线程的函数
  * @param  argument: 未使用
  * @retval 无
  */
/* USER CODE END Header_StartLCD_Task */
void StartLCD_Task(void *argument)
{
    uint8_t a;
    osDelay(1000);
    GpuSend("SPG(1);");
    GpuSend("\r\n");
    osDelay(1000);
    
    for (;;)
    {
        // 显示供电状态(交流/电池)
        if (rtu_buff[136] & 0X0001)
        {
            GpuSend("LABL(16,160,55,260,'交流供电中',3,1);");
        }
        else
        {
            GpuSend("LABL(16,160,55,260,'电池供电中',3,1);");
            ac_v_f = 0;
        }
        
        // 显示备电状态(断线/正常)
        if (BAT_EN == 0)
        {
            GpuSend("LABL(16,262,55,310,'断线中',3,0);");
        }
        else
        {
            GpuSend("LABL(16,262,55,310,'备电中',3,0);");
        }
        
        // 显示设备型号和交流电压
        GpuSend("LABL(16,90,85,150,'660/12B',3,0);");
        GpuSend("LABL(16,75,110,150,'%dV',3,0);", (uint16_t)(ac_v_f));
        
        // 显示输出电压电流
        GpuSend("LABL(16,235,85,314,'%.1fV%.1fA',3,0);", dc_v[0], dc_i[0]);
        GpuSend("LABL(16,235,110,314,'%.1fV%.1fA',3,0);", dc_v[1], dc_i[1]);
        
        // 显示电池参数
        GpuSend("LABL(16,90,185,160,'%.1fV',2,0);", battery_v);
        GpuSend("LABL(16,250,185,310,'%.2fA',2,0);", battery_i);
        GpuSend("LABL(16,250,205,310,'%.1f℃',2,0);", tempre);
        GpuSend("LABL(16,90,205,105,'%d',2,0);", battery_capacity);
        
        // 显示充放电状态
        if (num_pic_bat_status == 3)
        {
            GpuSend("LABL(16,170,155,218,'充电中',2,0);");
        }
        else if (num_pic_bat_status == 2)
        {
            GpuSend("LABL(16,170,155,218,'放电中',2,0);");
        }
        else if (num_pic_bat_status == 4)
        {
            GpuSend("LABL(16,170,155,218,'待机中',2,0);");
        }
        
        // 显示电池SOC图标
        GpuSend("PIC(218,155,%d);", num_pic_battery);
        
        // 显示Modbus波特率
        GpuSend("LABL(16,170,230,250,'波特率:%d',2,0);", modbue_Baud * 100);
        
        // 显示Modbus从机地址
        GpuSend("LABL(16,250,230,310,'地址:%d',2,0);", modbue_SlaveAddr);
        
        // 显示设备运行时间
        GpuSend("LABL(16,90,230,160,'运行:%dh',2,0);", (uint32_t)(HAL_GetTick() / 3600000));
        
        // 显示UDP状态
        if (udp_status == 1) {
            GpuSend("LABL(16,170,250,250,'UDP:开启',2,0);");
        } else {
            GpuSend("LABL(16,170,250,250,'UDP:关闭',2,0);");
        }
        
        // 显示输出通道总数
        GpuSend("LABL(16,250,250,310,'输出:%d路',2,0);", out_sum);
        
        GpuSend("\r\n");
        
        osDelay(1000);
    }
}

/* USER CODE BEGIN Header_Startmodbus_rtu */
/**
 * @brief  实现modbus_rtu线程的函数
 * @param  argument: 未使用
 * @retval 无
 */
/* USER CODE END Header_Startmodbus_rtu */
void Startmodbus_rtu(void *argument)
{
    uint16_t data;
    uint16_t RegBuff[128];
    uint8_t i;
    uint32_t cnt1 = 0, cnt2 = 0;
    uint8_t Fun;

    // 初始化寄存器缓冲区(前10个寄存器:1~10)
    for (i = 0; i < 10; i++)
    {
        RegBuff[i] = i + 1;
    }

    // 主循环
    for (;;)
    {
        // 如果RTU标志置位则处理请求
        if (rtu)
        {
            rtu = 0;  // 清除RTU标志

            // 更新接收计数器
            cnt2 = cnt1;
            cnt1 = rx_usart1_cnt;
            rx_usart1_cnt = 0;  // 重置接收计数器

            // 如果有数据则处理
            if (cnt1 != 0)
            {
                // 处理期间禁用USART1接收中断
                LL_USART_DisableIT_RXNE(USART1);

                // 解包Modbus帧
                if (MODEBUS_SLAVE_FramesUnpack(&ModebusHandle1, modbue_SlaveAddr, cnt1, &Fun) == MRTU_OK)
                {
                    switch (Fun)
                    {
                        // 读保持寄存器(03) / 读输入寄存器(04)
                        case MRTU_FUN_READ_HOLD:
                        case MRTU_FUN_READ_INPUT:
                            MODEBUS_SLAVE_ReadUnpack(&ModebusHandle1, &FrameInfo1);
                            MODEBUS_SLAVE_ReturnReadReg(&ModebusHandle1,
                                                        FrameInfo1.fun,
                                                        FrameInfo1.SlaveAddr,
                                                        FrameInfo1.StartReg,
                                                        FrameInfo1.RegNum,
                                                        rtu_buff);
                            break;

                        // 写单个寄存器(06)
                        case MRTU_FUN_WRITE:
                            MODEBUS_SLAVE_WriteUnpack(&ModebusHandle1, &FrameInfo1, &data);
                            calibration_i = 1;  // 设置校准标志
                            MODEBUS_SLAVE_ReturnWriteHoldReg(&ModebusHandle1,
                                                            FrameInfo1.SlaveAddr,
                                                            FrameInfo1.StartReg,
                                                            data);
                            break;

                        // 写多个寄存器(10)
                        case MRTU_FUN_MWRITE:
                            MODEBUS_SLAVE_WriteMultUnpack(&ModebusHandle1, &FrameInfo1, RegBuff);
                            
                            // 如果寄存器地址<0x800则更新RTU缓冲区
                            if (FrameInfo1.StartReg < 0x800)
                            {
                                memcpy(rtu_buff + FrameInfo1.StartReg,
                                       RegBuff,
                                       FrameInfo1.RegNum * 2);
                                MODEBUS_SLAVE_ReturnWriteMultHoldReg(&ModebusHandle1,
                                                                    FrameInfo1.SlaveAddr,
                                                                    FrameInfo1.StartReg,
                                                                    FrameInfo1.RegNum);
                            }
                            // 寄存器地址>=0x800则执行校准
                            else
                            {
                                // 电压校准(0xAAAA)
                                if (RegBuff[0] == 0xAAAA)
                                {
                                    uint8_t ch = RegBuff[1] - 1;
                                    if ((ch <= 12) && (dc_v[ch] != 0.0f))
                                    {
                                        v_k[ch] *= ((float)RegBuff[2] / 100.00f) / dc_v[ch];
                                    }
                                    writeFlashTest();  // 保存校准到Flash
                                }
                                // 电流校准(0xBBBB)
                                else if (RegBuff[0] == 0xBBBB)
                                {
                                    uint8_t ch = RegBuff[1] - 1;
                                    if ((ch <= 12) && (dc_i[ch] != 0.0f))
                                    {
                                        if (dc_i[ch] > 0.0f)
                                        {
                                            i_k_a[ch] *= ((float)RegBuff[2] / 100.00f) / dc_i[ch];
                                        }
                                        else
                                        {
                                            i_k_a[ch] = - (i_k_a[ch] * ((float)RegBuff[2] / 100.00f) / dc_i[ch]);
                                        }
                                    }
                                    writeFlashTest();  // 保存校准到Flash
                                }
                                MODEBUS_SLAVE_ReturnWriteMultHoldReg(&ModebusHandle1,
                                                                    FrameInfo1.SlaveAddr,
                                                                    FrameInfo1.StartReg,
                                                                    FrameInfo1.RegNum);
                            }
                            break;

                        // 写地址(11, 自定义功能)
                        case MRTU_FUN_WRITE_ADD:
                            MODEBUS_SLAVE_WriteUnpack(&ModebusHandle1, &FrameInfo1, &data);
                            MODEBUS_SLAVE_ReturnWrite_add(&ModebusHandle1,
                                                          FrameInfo1.SlaveAddr,
                                                          FrameInfo1.StartReg,
                                                          data);
                            break;

                        default:
                            break;
                    }
                }

                // 重新使能USART1接收中断
                LL_USART_EnableIT_RXNE(USART1);
            }
        }

        // 任务延迟100ms
        osDelay(100);
    }
}

/* USER CODE BEGIN Header_Startled_Task */
/**
 * @brief  实现myled_Task线程的函数
 * @param  argument: 未使用
 * @retval 无
 */
/* USER CODE END Header_Startled_Task */
void Startled_Task(void *argument)
{
    // 主循环
    for (;;)
    {
        // 如果UDP使能则每3s发送RTU数据
        if (udp_status == 1)
        {
            MODEBUS_SLAVE_ReturnReadReg(&ModebusHandle1,
                                        03,                // 功能码03
                                        modbue_SlaveAddr,  // Modbus从机地址
                                        128,               // 起始寄存器地址
                                        98,                // 寄存器数量
                                        rtu_buff);         // 数据缓冲区
        }

        // 任务延迟3000ms
        osDelay(3000);
    }
}

/* USER CODE BEGIN Header_Startbms_Task */
/**
 * @brief  实现mybms_task线程的函数(NiMH电池管理)
 * @param  argument: 未使用
 * @retval 无
 */
/* USER CODE END Header_Startbms_Task */
void Startbms_Task(void *argument)
{
    /* USER CODE BEGIN Startbms_Task */
    /* 无限循环 */
    uint8_t aaa = 0;
    uint8_t bat_disch_counter = 0;
    static uint8_t was_charging = 0;
    static uint8_t last_ac_present = 1;  // 1=有电，0=停电（与Bit0取反）
    static int idle_counter = 0;         // 待机计数器(秒)
    static int charge_reopen_block_counter = 0;  // 充电关闭后的防抖计时器(秒)
    static int soh_update_counter = 0;           // SOH更新计数器(秒)
    static float max_device_tem_soh = 0.0f;      // 最高温度记录(用于SOH计算)
    static int deep_discharge_count_soh = 0;     // 深度放电次数计数
    static int cycle_count_debounce_counter = 0;  // 循环计数防抖计时器(秒)
    static uint8_t cycle_count_state = 0;         // 循环计数状态机(0=初始,1=已充电到高阈值,2=已放电到低阈值)
    
    osDelay(2000);
    
    // 初始化电池容量百分比
    battery_capacity = (SOC * 100) / battery_capacity_rate;
    
    for (;;)
    {
        // 充电逻辑处理
        if (battery_i <= -0.05f)  // 充电检测
        {
            // 按充电效率积分SOC（A→mA·s→容量计数）
            battery_capacity += (-battery_i * 1000.0f * charge_efficiency) / 3600.0f;

            // 计算电芯电压并更新峰值（用于Delta V判据）
            float cell_num = (rtu_buff[137] == 0) ? 32.0f : (float)rtu_buff[137];
            float cell_v = (cell_num > 0.0f) ? (battery_v / cell_num) : battery_v;
            
            // 进入充电态的起始初始化：峰值与温升计数复位
            if (!was_charging)
            {
                peak_cell_voltage = cell_v;
                temp_rate_accum = 0.0f;
                temp_rate_sample_count = 0;
                last_device_tem_bms = device_tem;
            }
            
            // 更新电压峰值
            if (cell_v > peak_cell_voltage)
            {
                peak_cell_voltage = cell_v;
            }

            // 累计温升（1秒节拍），到1分钟求温升速率
            if (temp_rate_sample_count == 0)
            {
                last_device_tem_bms = device_tem;
            }
            temp_rate_accum += (device_tem - last_device_tem_bms);
            last_device_tem_bms = device_tem;
            temp_rate_sample_count++;
            
            // 每分钟计算一次温升速率
            if (temp_rate_sample_count >= 60)
            {
                float temp_rate = temp_rate_accum;  // 摄氏度/分钟（每秒累加，总共60秒）
                temp_rate_accum = 0.0f;
                temp_rate_sample_count = 0;
                
                // dT/dt终止判据
                if (temp_rate >= temp_rate_threshold)
                {
                    ch_stade = 0;                 // 关闭充电使能
                    bat_charge_indicator = 1;     // 置充电完成指示
                    charge_reopen_block_counter = charge_reopen_block_seconds;
                }
            }

            // 充电截止电流判据（涓流/末端小电流时终止）
            if ((-battery_i) <= charge_cutoff_current)
            {
                ch_stade = 0;
                bat_charge_indicator = 1;
                charge_reopen_block_counter = charge_reopen_block_seconds;
            }

            // Delta V终止判据：电芯电压从峰值回落达到阈值
            if ((peak_cell_voltage - cell_v) >= delta_v_threshold_per_cell)
            {
                ch_stade = 0;
                bat_charge_indicator = 1;
                charge_reopen_block_counter = charge_reopen_block_seconds;
            }

            // 满容量与高压钳位
            if (battery_capacity >= battery_capacity_rate || 
                battery_v >= (rtu_buff[137] * 1.45f))
            {
                battery_capacity = battery_capacity_rate;  // 钳制满容量
                bat_charge_indicator = 1;                  // 置充电完成指示
            }
        }
        
        // 放电逻辑处理
        if (battery_i >= 0.05f)  // 检测放电
        {
            // 按放电效率积分SOC（A→mA·s→容量计数）
            battery_capacity -= (battery_i * 1000.0f * discharge_efficiency) / 3600.0f;
            
            // 低电量指示
            if (battery_capacity <= 1000)
            {
                bat_discharge_indication = 1;
            }
        }
        
        // 电压保护逻辑 - 统一处理
        // 过压保护 (充电保护)
        if (battery_v >= (rtu_buff[137] * 1.4f))
        {
            battery_capacity = battery_capacity_rate;
            bat_charge_indicator = 1;
        }
        
        // 低电压判据（欠压保护，仅放电时计数）
        {
            float cell_num_uv = (rtu_buff[137] == 0) ? 32.0f : (float)rtu_buff[137];
            if ((battery_i >= 0.05f) && (battery_v <= (cell_num_uv * 0.9f)))
            {
                bat_disch_counter++;
                // 欠压需稳定5秒以上，避免毛刺触发
                if (bat_disch_counter >= 5)
                {
                    battery_capacity = 0;          // 强制为0
                    bat_disch_counter = 0;        // 清零计数器
                    // 欠压条件下允许充电使能打开
                    if (charge_reopen_block_counter == 0)
                    {
                        ch_stade = 1;
                    }
                }
            }
            else
            {
                bat_disch_counter = 0;  // 非欠压或非放电时清零
            }
        }
        
        // 容量上限钳位
        if (battery_capacity > battery_capacity_rate)
        {
            battery_capacity = battery_capacity_rate;
        }
        
        // 计算并更新容量百分比
        SOC = (battery_capacity * 100) / battery_capacity_rate;
        
        // 电池状态异常时强制SOC为0
        if (BAT_STATE1 == 0)
        {
            SOC = 0;
            battery_capacity = 0;
        }
        
        // 边界处理 - 确保SOC在有效范围
        if (SOC < 0)
        {
            SOC = 0;
        }
        
        // AC复电强制充电：检测rtu_buff[136]的Bit0从1(停电)到0(来电)
        {
            uint8_t ac_present = ((rtu_buff[136] & 0x0001) == 0) ? 1 : 0;
            if (!last_ac_present && ac_present)
            {
                ch_stade = 1;  // 复电后不论SOC，允许充电
            }
            last_ac_present = ac_present;
        }
        
        // 待机补电逻辑：长时间低电流时按SOC或电压阈值允许充电
        {
            float abs_i = (battery_i >= 0.0f) ? battery_i : -battery_i;
            if (abs_i < i_idle_threshold)
            {
                idle_counter++;
                if (idle_counter >= idle_debounce_seconds)
                {
                    float cell_num_idle = (rtu_buff[137] == 0) ? 32.0f : (float)rtu_buff[137];
                    float cell_v_idle = (cell_num_idle > 0.0f) ? (battery_v / cell_num_idle) : battery_v;
                    
                    // 待机自放电微弱泄漏（按天百分比折算到每秒）
                    float leak_mAh_per_sec = (battery_capacity_rate * standby_self_discharge_rate_percent_per_day) / (100.0f * 86400.0f);
                    if (cell_v_idle <= standby_safe_cell_v_threshold)
                    {
                        battery_capacity -= leak_mAh_per_sec;
                    }
                    
                    // 待机容量/电压回落到安全值以下，允许充电补电
                    if ((SOC <= standby_safe_soc_threshold) || (cell_v_idle <= standby_safe_cell_v_threshold))
                    {
                        if (charge_reopen_block_counter == 0)
                        {
                            ch_stade = 1;
                        }
                    }
                }
            }
            else
            {
                idle_counter = 0;  // 非待机状态，计数清零
            }
        }
        
        // 低SOC自动打开充电使能（需外部允许位生效）
        if ((battery_i > -0.05f) && (SOC <= 20))
        {
            if (charge_reopen_block_counter == 0)
            {
                ch_stade = 1;
            }
        }
        
        // 更新RTU电池相关寄存器
        rtu_buff[130] = SOC;
        rtu_buff[131] = SOH;
        rtu_buff[132] = battery_capacity;
        rtu_buff[133] = battery_capacity_full;
        rtu_buff[134] = battery_capacity_rate;
        rtu_buff[135] = battery_cyc;
        if (rtu_buff[137] == 0)
        {
            rtu_buff[137] = 32;  // 默认电芯数32
        }
        
        // 更新充电状态标志
        was_charging = (battery_i <= -0.05f);
        
        // SOH健康度更新逻辑
        soh_update_counter++;
        if (soh_update_counter >= SOH_UPDATE_INTERVAL_SECONDS)
        {
            soh_update_counter = 0;
            
            // 基于循环次数的健康度下降
            float cycle_degradation = battery_cyc * SOH_CYCLE_DEGRADATION_PER_CYCLE;
            
            // 基于温度的加速老化（超过40℃时）
            float temp_degradation = 0.0f;
            if (max_device_tem_soh > 40.0f)
            {
                temp_degradation = (max_device_tem_soh - 40.0f) * SOH_TEMPERATURE_DEGRADATION_PER_DEGREE;
            }
            
            // 基于深度放电的健康度下降
            float deep_discharge_degradation = deep_discharge_count_soh * SOH_DEEP_DISCHARGE_DEGRADATION;
            
            // 计算总健康度下降
            float total_degradation = cycle_degradation + temp_degradation + deep_discharge_degradation;
            
            // 更新SOH（不低于20%）
            SOH = (uint16_t)fmaxf(20.0f, 100.0f - total_degradation);
            
            // 更新额定容量（基于健康度）
            battery_capacity_rate = battery_capacity_full * (SOH / 100.0f);
            
            // 重置统计量
            max_device_tem_soh = 0.0f;
            deep_discharge_count_soh = 0;
        }

        // 记录最高温度
        if (device_tem > max_device_tem_soh)
        {
            max_device_tem_soh = device_tem;
        }

        // 检测深度放电（SOC低于10%且正在放电）
        if (SOC < 10 && battery_i > 0.05f)
        {
            deep_discharge_count_soh++;
        }

        // 循环计数防抖计时器递减
        if (cycle_count_debounce_counter > 0)
        {
            cycle_count_debounce_counter--;
        }
        
        // 循环计数逻辑（状态机实现）
        if (cycle_count_debounce_counter == 0)
        {
            // 状态0: 初始状态，等待充电到高阈值
            if (cycle_count_state == 0 && SOC >= CYCLE_COUNT_SOC_THRESHOLD_HIGH)
            {
                cycle_count_state = 1;  // 进入已充电状态
            }
            // 状态1: 已充电到高阈值，等待放电到低阈值
            else if (cycle_count_state == 1 && SOC <= CYCLE_COUNT_SOC_THRESHOLD_LOW)
            {
                cycle_count_state = 2;  // 进入已放电状态
            }
            // 状态2: 已放电到低阈值，完成一个循环
            else if (cycle_count_state == 2 && SOC >= CYCLE_COUNT_SOC_THRESHOLD_HIGH)
            {
                battery_cyc++;               // 增加循环次数
                cycle_count_state = 0;       // 重置状态机
                cycle_count_debounce_counter = CYCLE_COUNT_DEBOUNCE_SECONDS;  // 启动防抖计时器
            }
        }

        // 充电关闭防抖计时器递减（1秒节拍）
        if (charge_reopen_block_counter > 0)
        {
            charge_reopen_block_counter--;
        }
        
        osDelay(1000);
    }
    /* USER CODE END Startbms_Task */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/**
 * @brief  实现TC_Task线程的函数(ADC采样与传感器数据处理)
 * @param  argument: 未使用
 * @retval 无
 */
void Start_TC_Task(void *argument)
{
    float adc_voltage;          // ADC采样电压(mV)
    float bus_v, current, shunt_v;  // INA226数据(总线电压, 电流, 分流电压)
    uint8_t res;                // INA226操作结果(0=成功)
    uint16_t ctrl;              // 告警状态控制寄存器
    int16_t RegBuff[30];        // Modbus寄存器缓冲区
    uint8_t ii1 = 0;            // 通信错误计数器1
    uint8_t ii2 = 0;            // 通信错误计数器2(未使用)
    uint8_t ii3 = 0;            // 通信错误计数器3(未使用)

    // 配置USART1 DMA发送
    LL_USART_EnableDMAReq_TX(USART1);
    LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_4, (uint32_t)ModebusTxBuff);
    LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_4, (uint32_t)(&USART1->DR));
    
    // 使能USART1接收中断和DMA传输完成中断
    LL_USART_EnableIT_RXNE(USART1);
    LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_4);
    
    // 初始化Modbus主机(UARTx, 从机地址1, 波特率115200)
    MODEBUS_host_Init(&ModebusHandle2, 01, 115200, ModebusRxBuff_M, ModebusTxBuff_M, 128-1, 200);
    
    // 重置校准标志
    calibration_i = 0;

    // 系统延迟200ms
    LL_mDelay(200);

    // 初始化INA226(dev1, 地址0x40)
    res = INA226_Init(&dev1);
    if (res != INA226_OK)
    {
        res = INA226_Init(&dev1);  // 重试一次
        OUT1_266 = (res == INA226_OK) ? 1 : 0;
    }
    else
    {
        OUT1_266 = 1;
    }

    // 系统延迟200ms
    LL_mDelay(200);

    // 初始化INA226(dev2, 地址0x41)
    res = INA226_Init(&dev2);
    if (res != INA226_OK)
    {
        res = INA226_Init(&dev2);  // 重试一次
        OUT2_266 = (res == INA226_OK) ? 1 : 0;
    }
    else
    {
        OUT2_266 = 1;
    }

    // 初始化INA226(dev3, 地址0x42)
    res = INA226_Init(&dev3);
    if (res != INA226_OK)
    {
        res = INA226_Init(&dev1);  // 重试dev1(备用)
        OUT1_266 = (res == INA226_OK) ? 1 : 0;
    }
    else
    {
        OUT1_266 = 1;
    }

    // 系统延迟200ms
    LL_mDelay(200);

    // 初始化INA226(dev4, 地址0x44)
    res = INA226_Init(&dev4);
    if (res != INA226_OK)
    {
        res = INA226_Init(&dev2);  // 重试dev2(备用)
        OUT2_266 = (res == INA226_OK) ? 1 : 0;
    }
    else
    {
        OUT2_266 = 1;
    }

    // 主循环
    for (;;)
    {
        // 如果模式为1则处理Modbus通信
        if (m_s == 1)
        {
            // 当out_sum >= 6时从从机设备读取电压/电流数据
            if (out_sum >= 6)
            {
                // 读取从地址157开始的3个寄存器
                if (MODEBUS_HOST_ReadMultReg(&ModebusHandle2, 3, 2, 157, 3, RegBuff) == MRTU_OK)
                {
                    ii1 = 0;  // 重置错误计数器
                    // 复制数据到RTU缓冲区
                    memcpy(rtu_buff + 163, RegBuff, 3 * 2);
                
                    // 转换RTU值为实际电压(V = 值 / 100)
                    dc_v[3] = (float)(rtu_buff[163]) / 100.0f;
                    dc_v[4] = (float)(rtu_buff[165]) / 100.0f;
                    dc_v[5] = (float)(rtu_buff[167]) / 100.0f;
                
                    // 转换RTU值为实际电流(A = 值 / 100)
                    dc_i[3] = (float)(rtu_buff[164]) / 100.0f;
                    dc_i[4] = (float)(rtu_buff[166]) / 100.0f;
                    dc_i[5] = (float)(rtu_buff[168]) / 100.0f;
                }
                else
                {
                    ii1++;  // 增加错误计数器
                    // 如果错误计数超过5则设置数据为0
                    if (ii1 > 5)
                    {
                        dc_v[3] = 0.0f;
                        dc_v[4] = 0.0f;
                        dc_v[5] = 0.0f;
                    
                        dc_i[3] = 0.0f;
                        dc_i[4] = 0.0f;
                        dc_i[5] = 0.0f;
                    
                        rtu_buff[163] = 0;
                        rtu_buff[164] = 0;
                        rtu_buff[165] = 0;
                        rtu_buff[166] = 0;
                        rtu_buff[167] = 0;
                        rtu_buff[168] = 0;
                    }
                }

                // 读取从地址128开始的1个寄存器(电池电流)
                if (MODEBUS_HOST_ReadMultReg(&ModebusHandle2, 3, 2, 128, 1, RegBuff) == MRTU_OK)
                {
                    ii1 = 0;  // 重置错误计数器
                    // 转换为实际电流(A = 值 / 100)
                    battery_i1 = (float)(RegBuff[0]) / 100.0f;
                }
                else
                {
                    ii1++;  // 增加错误计数器
                    // 如果错误计数超过5则设置为0
                    if (ii1 > 5)
                    {
                        battery_i1 = 0.0f;
                    }
                }

                // 向从机设备写入1个寄存器(ctrl_2)
                MODEBUS_HOST_WriteMultReg(&ModebusHandle2, 2, 3, 1, &ctrl_2);
            }
        }

        // -------------------------- 校准处理 --------------------------
        if (calibration_i == 1)
        {
            calibration_i = 0;  // 清除校准标志(此情况无动作)
        }
        else if (calibration_i == 2)
        {
            calibration_i = 0;  // 清除校准标志
            writeFlashTest();   // 保存校准数据到Flash
        }

        // -------------------------- 温度采样(ADC1_IN7) --------------------------
        // 查找温度索引(从查找表)
        for (tem = 0; tem < 340; tem++)
        {
            if (t_adc[tem] > aADCxConvertedData[0])
            {
                break;
            }
        }
        
        // 计算温度(0.1℃单位: tem-40 = ℃, *10 = 0.1℃)
        tem = (tem - 40) * 10;
        
        // 温度边界: -400 (=-40℃) ~ 1250 (=125℃)
        if (tem < -400)
        {
            tem = -400;
        }
        if (tem > 1250)
        {
            tem = 1250;
        }
        
        // 转换为实际温度(℃)并更新RTU缓冲区
        device_tem = (float)tem / 10.00f;
        rtu_buff[138] = tem;

        // -------------------------- INA226数据采样 --------------------------
        // 采样INA226(dev1, 地址0x40)
        res = INA226_ReadAll(&dev1, &bus_v, &current, &shunt_v);
        if (res != INA226_OK)
        {
            res = INA226_ReadAll(&dev1, &bus_v, &current, &shunt_v);  // 重试一次
        }
        // 计算实际电压/电流(带校准, 失败则为0)
        dc_v[0] = (res == INA226_OK) ? (bus_v * v_k[0]) : 0.0f;
        dc_i[0] = (res == INA226_OK) ? (current * i_k_a[0] / 1.05f) : 0.0f;
        // 更新RTU缓冲区(保留2位小数: 值 * 100)
        rtu_buff[157] = (uint16_t)(dc_v[0] * 100);
        rtu_buff[158] = (uint16_t)(dc_i[0] * 100);

        // 采样INA226(dev2, 地址0x41)
        res = INA226_ReadAll(&dev2, &bus_v, &current, &shunt_v);
        if (res != INA226_OK)
        {
            res = INA226_ReadAll(&dev2, &bus_v, &current, &shunt_v);  // 重试一次
        }
        dc_v[0] = (res == INA226_OK) ? (bus_v * v_k[0]) : 0.0f;
        dc_i[0] = (res == INA226_OK) ? (current * i_k_a[0] / 1.05f) : 0.0f;
        rtu_buff[159] = (uint16_t)(dc_v[0] * 100);
        rtu_buff[160] = (uint16_t)(dc_i[0] * 100);

        // 采样INA226(dev3, 地址0x42)
        res = INA226_ReadAll(&dev3, &bus_v, &current, &shunt_v);
        if (res != INA226_OK)
        {
            res = INA226_ReadAll(&dev3, &bus_v, &current, &shunt_v);  // 重试一次
        }
        dc_v[0] = (res == INA226_OK) ? (bus_v * v_k[0]) : 0.0f;
        dc_i[0] = (res == INA226_OK) ? (current * i_k_a[0] / 1.05f) : 0.0f;
        rtu_buff[161] = (uint16_t)(dc_v[0] * 100);
        rtu_buff[162] = (uint16_t)(dc_i[0] * 100);

        // 采样INA226(dev4, 地址0x44 - 电池)
        res = INA226_ReadAll(&dev4, &bus_v, &current, &shunt_v);
        if (res != INA226_OK)
        {
            res = INA226_ReadAll(&dev4, &bus_v, &current, &shunt_v);  // 重试一次
        }
        dc_v[12] = (res == INA226_OK) ? (bus_v * v_k[12]) : 0.0f;
        dc_i[12] = (res == INA226_OK) ? (current * i_k_a[12] / 1.05f) : 0.0f;
        
        // 计算总电池电压和电流
        battery_v = dc_v[12];
        battery_i = dc_i[12] + battery_i1;
        
        // 更新RTU缓冲区(电流: int16_t, 电压: uint16_t)
        rtu_buff[128] = (int16_t)(battery_i * 100);
        rtu_buff[129] = (uint16_t)(dc_v[12] * 100);

        // 任务延迟100ms
        osDelay(100);

        // -------------------------- 电池状态标志更新 --------------------------
        // 根据电流设置充/放/ idle标志
        if (battery_i < -0.1f)
        {
            num_pic_bat_status = 3;  // 充电中
        }
        else if (battery_i > 0.1f)
        {
            num_pic_bat_status = 2;  // 放电中
        }
        else
        {
            num_pic_bat_status = 4;  // 待机中
        }

        // -------------------------- 电池SOC显示标志更新 --------------------------
        if (battery_capacity <= 20)
        {
            num_pic_battery = 5;  // 低SOC (<=20%)
        }
        else if (battery_capacity <= 40)
        {
            num_pic_battery = 4;  // 20% < SOC <=40%
        }
        else if (battery_capacity <= 60)
        {
            num_pic_battery = 3;  // 40% < SOC <=60%
        }
        else if (battery_capacity <= 80)
        {
            num_pic_battery = 2;  // 60% < SOC <=80%
        }
        else
        {
            num_pic_battery = 1;  // 高SOC (>80%)
        }

        // -------------------------- 系统RTU寄存器更新 --------------------------
        if (rtu_buff[137] == 0)
        {
            rtu_buff[137] = 32;  // 电池电芯数可配置; 默认32
        }
        rtu_buff[151] = modbue_SlaveAddr;  // 当前Modbus从机地址
        rtu_buff[152] = modbue_Baud;       // 当前Modbus波特率

        // -------------------------- 告警状态更新 --------------------------
        ctrl = rtu_buff[136];  // 读取当前告警状态

        // Bit0: AC电源状态(PG引脚低=AC存在, 高=AC不存在)
        if (!LL_GPIO_IsInputPinSet(PG_GPIO_Port, PG_Pin))
        {
            rtu_buff[136] = (ctrl & 0xFFFE);  // AC存在: Bit0 = 0
            POWER_STATE = 1;                  // 电源状态: AC
        }
        else
        {
            rtu_buff[136] = (ctrl | 0x0001);  // AC不存在: Bit0 = 1
            POWER_STATE = 0;                  // 电源状态: DC
        }

        // Bit1: 低SOC告警(SOC <=20%)
        ctrl = rtu_buff[136];  // 读取更新后的状态
        if (battery_capacity <= 20)
        {
            rtu_buff[136] = (ctrl | 0x0002);  // 告警: Bit1 = 1
        }
        else
        {
            rtu_buff[136] = (ctrl & 0xFFFD);  // 无告警: Bit1 = 0
        }

        // Bit2: 高温告警(设备温度 >=50℃)
        ctrl = rtu_buff[136];  // 读取更新后的状态
        if (device_tem >= 50.0f)
        {
            rtu_buff[136] = (ctrl | 0x0004);  // 告警: Bit2 = 1
        }
        else
        {
            rtu_buff[136] = (ctrl & 0xFFFB);  // 无告警: Bit2 = 0
        }

        // Bit3: 低温告警(设备温度 <=-20℃)
        ctrl = rtu_buff[136];  // 读取更新后的状态
        if (device_tem <= -20.0f)
        {
            rtu_buff[136] = (ctrl | 0x0008);  // 告警: Bit3 = 1
        }
        else
        {
            rtu_buff[136] = (ctrl & 0xFFF7);  // 无告警: Bit3 = 0
        }

        // Bit4: 低电压告警(dc_v[0] <=10V)
        ctrl = rtu_buff[136];  // 读取更新后的状态
        if (dc_v[0] <= 10.0f)
        {
            rtu_buff[136] = (ctrl | 0x0010);  // 告警: Bit4 = 1
        }
        else
        {
            rtu_buff[136] = (ctrl & 0xFFEF);  // 无告警: Bit4 = 0
        }
        
        // 读取模式选择引脚(M_S)
        if (LL_GPIO_IsInputPinSet(M_S_GPIO_Port, M_S_Pin))
        {
            m_s = 1;
        }
        else
        {
            m_s = 0;
        }
        
        // 读取地址选择引脚(D1,D2)
        if (LL_GPIO_IsInputPinSet(D1_GPIO_Port, D1_Pin) & LL_GPIO_IsInputPinSet(D2_GPIO_Port, D2_Pin))
        {
            add = 2;
        }
        else if ((!LL_GPIO_IsInputPinSet(D1_GPIO_Port, D1_Pin)) & LL_GPIO_IsInputPinSet(D2_GPIO_Port, D2_Pin))
        {
            add = 3;
        }
        else if (LL_GPIO_IsInputPinSet(D1_GPIO_Port, D1_Pin) & (!LL_GPIO_IsInputPinSet(D2_GPIO_Port, D2_Pin)))
        {
            add = 4;
        }
        else if ((!LL_GPIO_IsInputPinSet(D1_GPIO_Port, D1_Pin)) & (!LL_GPIO_IsInputPinSet(D2_GPIO_Port, D2_Pin)))
        {
            add = 5;
        }
        
        // 读取PCB数量选择引脚(LU1,LU2)
        if (m_s == 1)
        {
            if (LL_GPIO_IsInputPinSet(LU1_GPIO_Port, LU1_Pin) & LL_GPIO_IsInputPinSet(LU2_GPIO_Port, LU2_Pin))
            {
                pcb_sum = 2;
            }
            else if ((!LL_GPIO_IsInputPinSet(LU1_GPIO_Port, LU1_Pin)) & LL_GPIO_IsInputPinSet(LU2_GPIO_Port, LU2_Pin))
            {
                pcb_sum = 3;
            }
            else if (LL_GPIO_IsInputPinSet(LU1_GPIO_Port, LU1_Pin) & (!LL_GPIO_IsInputPinSet(LU2_GPIO_Port, LU2_Pin)))
            {
                pcb_sum = 4;
            }
            else if ((!LL_GPIO_IsInputPinSet(LU1_GPIO_Port, LU1_Pin)) & (!LL_GPIO_IsInputPinSet(LU2_GPIO_Port, LU2_Pin)))
            {
                pcb_sum = 5;
            }
        }
        else
        {
            pcb_sum = 1;
        }
        
        // 更新输出总数并设置LCD刷新标志
        out_sum_temp = out_sum;
        out_sum = pcb_sum * 3;
        rtu_buff[156] = out_sum;
        
        if (out_sum_temp != out_sum)
        {
            out_lcd = 0;
        }
        else
        {
            out_lcd = 1;
        }
        
        // 任务延迟200ms
        osDelay(200);
    }
}

/**
 * @brief  实现cmd_Task线程的函数(PC命令处理)
 * @param  argument: 未使用
 * @retval 无
 */
void Start_cmd_Task(void *argument)
{
    uint8_t tmp, crc;
    uint16_t cmd_crc;
    uint16_t ctrl_temp;
    uint8_t buff[10];
    static uint8_t rx_state_pc = 0;  // UART1接收状态(0=空闲, 1=接收中)
    static uint8_t rx_cont = 0;      // UART1接收计数器
    uint8_t cChar;

    // 创建UART1接收同步的二进制信号量
    vSemaphoreCreateBinary(xSemaphoreRecf_pc_uart1);
    // 创建UART1接收队列(50个元素, 每个1字节)
    xQueueRx_pc_uart1 = xQueueCreate(50, sizeof(uint8_t));
    // 初始化命令CRC值
    cmd_crc = 0;

    // 使能USART1接收中断
    LL_USART_EnableIT_RXNE(USART1);
    // 系统延迟2000ms
    osDelay(2000);

    // 主循环
    for (;;)
    {
        // -------------------------- 控制寄存器计算 --------------------------
        // 计算ctrl_2: 来自rtu_buff[3]的位4~15(12位)
        ctrl_2 = (rtu_buff[3] >> 3) & 0x0FFF;
        ctrl_temp = rtu_buff[3] & 0xF000;
        ctrl_2 = ctrl_2 | ctrl_temp;

        // 计算ctrl_3: 来自rtu_buff[3]的位8~15(8位) + 位4~7(4位)
        ctrl_3 = (rtu_buff[3] >> 6) & 0x0FFF;
        ctrl_temp = rtu_buff[3] & 0xF000;
        ctrl_3 = ctrl_3 | ctrl_temp;

        // -------------------------- GPIO控制(输出使能) --------------------------
        // EN_1控制(rtu_buff[3]的bit0: 1=使能, 0=禁用)
        if (rtu_buff[3] & 0x0001)
        {
            LL_GPIO_ResetOutputPin(EN_1_GPIO_Port, EN_1_Pin);  // 低电平=使能
        }
        else
        {
            LL_GPIO_SetOutputPin(EN_1_GPIO_Port, EN_1_Pin);    // 高电平=禁用
        }

        // EN_AC控制(rtu_buff[3]的bit12: 1=使能, 0=禁用)
        if (rtu_buff[3] & 0x1000)
        {
            LL_GPIO_ResetOutputPin(EN_AC_GPIO_Port, EN_AC_Pin);  // 低电平=使能
        }
        else
        {
            LL_GPIO_SetOutputPin(EN_AC_GPIO_Port, EN_AC_Pin);    // 高电平=禁用
        }

        // EN_BAT控制(rtu_buff[3]的bit13 + BAT_EN标志: 都为1时使能)
        if ((rtu_buff[3] & 0x2000) && BAT_EN)
        {
            LL_GPIO_ResetOutputPin(EN_BAT_GPIO_Port, EN_BAT_Pin);  // 低电平=使能
        }
        else
        {
            writeFlashTest();
            LL_GPIO_SetOutputPin(EN_BAT_GPIO_Port, EN_BAT_Pin);    // 高电平=禁用
        }

        // EN_CH控制(rtu_buff[3]的bit14 + 充电状态标志: 都为1时使能)
        if ((rtu_buff[3] & 0x4000) && ch_stade && BAT_STATE1 && bat_stade1)
        {
            LL_GPIO_SetOutputPin(EN_CH_GPIO_Port, EN_CH_Pin);    // 高电平=使能
        }
        else
        {
            LL_GPIO_ResetOutputPin(EN_CH_GPIO_Port, EN_CH_Pin);  // 低电平=禁用
        }

        // -------------------------- RTU寄存器更新 --------------------------
        // 同步控制寄存器到RTU缓冲区(rtu_buff[155] = rtu_buff[3])
        rtu_buff[155] = rtu_buff[3];

        // 电池循环计数已迁移到Startbms_Task中的状态机实现
        // 此处保留原有逻辑但不再执行计数，避免重复计数

        // -------------------------- Flash数据同步 --------------------------
        // 如果模式为1，同步配置参数到Flash
        if (m_s == 1)
        {
            // 同步Modbus从机地址(如果改变)
            if (rtu_buff[6] != modbue_SlaveAddr)
            {
                modbue_SlaveAddr = rtu_buff[6];
                writeFlashTest();
            }

            // 同步UDP状态(如果改变)
            if (rtu_buff[154] != udp_status)
            {
                udp_status = rtu_buff[154];
                writeFlashTest();
            }

            // 同步Modbus波特率(如果改变)
            if (rtu_buff[4] != modbue_Baud)
            {
                modbue_Baud = rtu_buff[4];
                // 动态重配置USART1波特率，无需重启
                USART1_Reconfigure_BaudRate(modbue_Baud);
                writeFlashTest();
            }

            // 同步欠充阈值(如果改变)
            if (rtu_buff[5] != SOH)
            {
                SOH = rtu_buff[5];
                writeFlashTest();
            }

            // 同步电池循环计数(如果改变)
            if (rtu_buff[7] != battery_cyc)
            {
                battery_cyc = rtu_buff[7];
                writeFlashTest();
            }
        }
        // 模式为0时使用硬件引脚配置
        else
        {
            modbue_SlaveAddr = add;
            modbue_Baud = 1152;
            USART1_Reconfigure_BaudRate(modbue_Baud);
        }

        // 任务延迟200ms
        osDelay(200);
    }
}
/* USER CODE END Application */